﻿using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Internal.Core;
using ArcGIS.Desktop.Internal.Mapping;
using ArcGIS.Desktop.Mapping;
using Aspose.Cells;
using CCTool.Scripts.CusTool3;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Library;
using CCTool.Scripts.ToolManagers.Managers;
using Microsoft.Office.Core;
using NPOI.OpenXmlFormats.Vml;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Row = ArcGIS.Core.Data.Row;

namespace CCTool.Scripts.CusTool4
{
    /// <summary>
    /// Interaction logic for MultiCG.xaml
    /// </summary>
    public partial class MultiCG : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        // 工具设置标签
        readonly string toolSet = "MultiCG";

        public MultiCG()
        {
            InitializeComponent();
            Init();

            //UITool.InitFeatureLayerToComboxPlus(combox_fc, "JQDLTB");
            //UITool.InitFeatureLayerToComboxPlus(combox_fc_gh, "GHDLTB");
            //UITool.InitFieldToComboxPlus(combox_bmField, "JQDLBM", "string");
            //UITool.InitFieldToComboxPlus(combox_bmField_gh, "GHDLBM", "string");
            //UITool.InitFieldToComboxPlus(combox_areaField, "SHAPE_Area", "float");
            //UITool.InitFieldToComboxPlus(combox_areaField_gh, "SHAPE_Area", "float");

            //UITool.InitFeatureLayerToComboxPlus(combox_dltb, "DLTB");
            //UITool.InitFeatureLayerToComboxPlus(combox_jsbj, "村庄建设边界");
        }

        // 初始化
        private void Init()
        {
            combox_unit.Items.Add("平方米");
            combox_unit.Items.Add("公顷");
            combox_unit.Items.Add("平方公里");
            combox_unit.Items.Add("亩");

            _ = int.TryParse(BaseTool.ReadValueFromReg(toolSet, "unit_index"), out int unit_index);
            combox_unit.SelectedIndex = unit_index;

            combox_digit.Items.Add("1");
            combox_digit.Items.Add("2");
            combox_digit.Items.Add("3");
            combox_digit.Items.Add("4");
            combox_digit.Items.Add("5");
            combox_digit.Items.Add("6");

            _ = int.TryParse(BaseTool.ReadValueFromReg(toolSet, "digit_index"), out int digit_index);
            combox_digit.SelectedIndex = digit_index;

            // 初始化其它参数选项
            textOutPath.Text = BaseTool.ReadValueFromReg(toolSet, "outPath");

            textXZQ.Text = BaseTool.ReadValueFromReg(toolSet, "xzq");
            textGBMJ.Text = BaseTool.ReadValueFromReg(toolSet, "gbmj");

        }

        // 定义一个进度框
        private ProcessWindow processwindow = null;
        string tool_name = "复杂的村庄指标统计(奶糖)";

        // 点击打开按钮
        private void openFolderButton_Click(object sender, RoutedEventArgs e)
        {
            // 打开Excel文件
            string path = UITool.OpenDialogFolder();
            // 将Excel文件的路径置入【textExcelPath】
            textOutPath.Text = path;
        }

        // 添加要素图层的所有字符串字段到combox中
        private void combox_field_DropDown(object sender, EventArgs e)
        {
            // 将图层字段加入到Combox列表中
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_bmField);
        }

        private void combox_fc_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_fc);
        }

        // 运行
        private async void btn_go_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取默认数据库
                var init_gdb = Project.Current.DefaultGeodatabasePath;
                // 获取参数
                string fc_path = combox_fc.ComboxText();
                string field_bm = combox_bmField.ComboxText();
                string areaField = combox_areaField.ComboxText();

                string fc_path_gh = combox_fc_gh.ComboxText();
                string field_bm_gh = combox_bmField_gh.ComboxText();
                string areaField_gh = combox_areaField_gh.ComboxText();

                //  参照图层
                string dltb = combox_dltb.ComboxText();
                string jsbj = combox_jsbj.ComboxText();

                string output_table = init_gdb + @"\output_table";
                string outPath = textOutPath.Text;
                string xzq = textXZQ.Text;

                string unit = combox_unit.Text;
                int digit = int.Parse(combox_digit.Text);

                string gbmj = textGBMJ.Text;

                // 判断参数是否选择完全
                if (fc_path == "" || field_bm == "" || areaField == "" || fc_path_gh == "" || field_bm_gh == "" || areaField_gh == "" || output_table == "")
                {
                    MessageBox.Show("有必选参数为空！！！");
                    return;
                }


                // 保存参数
                BaseTool.WriteValueToReg(toolSet, "outPath", outPath);
                BaseTool.WriteValueToReg(toolSet, "xzq", xzq);
                BaseTool.WriteValueToReg(toolSet, "gbmj", gbmj);

                BaseTool.WriteValueToReg(toolSet, "unit_index", combox_unit.SelectedIndex);
                BaseTool.WriteValueToReg(toolSet, "digit_index", combox_digit.SelectedIndex);

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                // 单位系数设置
                double unit_xs = unit switch
                {
                    "平方米" => 1,
                    "公顷" => 10000,
                    "平方公里" => 1000000,
                    "亩" => 666.66667,
                    _ => 1,
                };

                Close();

                await QueuedTask.Run(() =>
                {
                    StateData sd = new StateData();
                    // 写入数据
                    sd.XZQ = xzq;
                    sd.xzPath = fc_path;
                    sd.ghPath = fc_path_gh;

                    sd.xzBM = field_bm;
                    sd.ghBM = field_bm_gh;

                    sd.xzField = areaField;
                    sd.ghField = areaField_gh;

                    sd.DLTB = dltb;
                    sd.JSBJ = jsbj;

                    sd.UnitName = unit;
                    sd.Digit = digit;
                    sd.OutputFolder = outPath;
                    sd.OutputExcel = $@"{outPath}\奶糖_统计表.xlsx";
                    sd.OutputWord = $@"{outPath}\指标说明.docx";

                    sd.XZQMJ = GisTool.GetFieldTotalFromPath(sd.xzPath, sd.xzField) / 10000;

                    sd.GBMJ = gbmj.ToDouble().ToString();

                    pw.AddMessageStart("检查数据");
                    // 检查数据
                    List<string> errs = CheckData(sd, fc_path, field_bm, fc_path_gh, field_bm_gh);
                    // 打印错误
                    if (errs.Count > 0)
                    {
                        foreach (var err in errs)
                        {
                            pw.AddMessageMiddle(10, err, Brushes.Red);
                        }
                        return;
                    }


                    pw.AddMessageMiddle(5, "计算现状和规划的净面积和田坎面积");
                    // 根据扣除系数计算净面积和田坎面积
                    GetReportData(sd);

                    // 汇总指标
                    Dictionary<string, double> dic_xz = ComboTool.StatisticsPlus(sd.xzPath, sd.xzBM, sd.areaField, "合计", unit_xs);
                    Dictionary<string, double> dic_gh = ComboTool.StatisticsPlus(sd.ghPath, sd.ghBM, sd.areaField, "合计", unit_xs);

                    // 指标分割
                    Dictionary<string, double> dic_splite_xz = ComboTool.DecomposeSummary(dic_xz);
                    Dictionary<string, double> dic_splite_gh = ComboTool.DecomposeSummary(dic_gh);
                    // 加入田坎面积
                    dic_splite_xz.Add("2303", sd.xzTK / unit_xs);
                    dic_splite_gh.Add("2303", sd.ghTK / unit_xs);

                    dic_splite_xz["合计"] += sd.xzTK / unit_xs;
                    dic_splite_gh["合计"] += sd.ghTK / unit_xs;

                    // 写入数据
                    sd.XZDict = dic_splite_xz;
                    sd.GHDict = dic_splite_gh;

                    // 复制嵌入资源中的Excel文件
                    DirTool.CopyResourceFile(@$"CCTool.Data.Excel.杂七杂八.奶糖_统计表.xlsx", $@"{sd.OutputExcel}");

                    pw.AddMessageMiddle(5, "现状面积统计表");
                    // 现状面积统计表
                    WriteExcel01(sd);
                    pw.AddMessageMiddle(5, "国土空间用途结构调整表");
                    // 国土空间用途结构调整表
                    WriteExcel02(sd);

                    pw.AddMessageMiddle(5, "规划前后建设用地面积对比表");
                    // 规划前后建设用地面积对比表
                    WriteExcel04(sd);

                    pw.AddMessageMiddle(5, "规划前后三大类面积对比表");
                    // 规划前后三大类面积对比表
                    WriteExcel03(sd);

                    pw.AddMessageMiddle(10, "计算村庄建设用地和农用地之间的转换细节");
                    // 计算村庄建设用地和农用地之间的转换细节
                    JSYDAndNYD(sd);


                    pw.AddMessageMiddle(20, "写入Word 说明");
                    // 写入Word 说明
                    WriteWord(sd);

                    pw.AddMessageMiddle(20, "消除中间数据");
                    // 消除中间数据
                    string defGDB = Project.Current.DefaultGeodatabasePath;
                    Arcpy.Delect(@$"{defGDB}\intersect_path");
                    Arcpy.Delect(@$"{defGDB}\identity_path");
                    Arcpy.DeleteField(sd.JSBJ, "YSBJ");
                    Arcpy.DeleteField(sd.ghPath, "BJYMJ;newXS");
                    Arcpy.DeleteField(sd.xzPath, "BJYMJ;newXS");

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }

        }


        // 计算村庄建设用地和农用地之间的转换细节
        private void JSYDAndNYD(StateData sd)
        {
            // 村庄建设用地转农用地
            Dictionary<string, double> czyd2nyd = new Dictionary<string, double>();
            // 农用地转村庄建设用地
            Dictionary<string, double> nyd2czyd = new Dictionary<string, double>();

            string defGDB = Project.Current.DefaultGeodatabasePath;

            // 相交
            string intersect_path = @$"{defGDB}\intersect_path";
            Arcpy.Intersect(new List<string>() { sd.xzPath, sd.ghPath }, intersect_path);
            // 标识
            Arcpy.AddField(sd.JSBJ, "YSBJ");
            Arcpy.CalculateField(sd.JSBJ, "YSBJ", "'边界内'");

            string identity_path = @$"{defGDB}\identity_path";
            Arcpy.Identity(intersect_path, sd.JSBJ, identity_path);


            // 村庄建设用地
            List<string> czjsKeys = new List<string>()
            {
                "070101", "070102", "070103", "0702", "070301", "070302", "0704", "0801", "0802" ,
                "080301", "080302", "080401", "080402", "080403", "080404", "080405", "080501", "080502" ,
                "080601", "080602", "080603", "080701", "080702", "080703", "080704",
                "090101", "090102", "090103", "090104", "090105", "0902", "0903", "0904",
                "100101", "100102", "100103",
                "110101", "110102", "110103", "1102",
                "1207", "120801", "120802", "120803", "1209",
                "1301", "1302", "1303", "1304", "1305", "1306", "1307", "1308", "1309" ,
                "1310", "1312", "1401", "1402", "16",
            };

            // 农用地
            List<string> nydKeys = new List<string>()
            {
                "0101", "0102", "0103", "0201", "0202", "0203", "0204", "0205",
                "0301", "0302", "0303", "0304", "0401", "0402", "0403",
                "060101", "060102", "060201", "060202", "060203",
                "1703", "1704", "1705",
            };

            using Table table = identity_path.TargetFeatureClass();
            using RowCursor rowCursor = table.Search();
            while (rowCursor.MoveNext())
            {
                Row row = rowCursor.Current;

                string xz_dl = row[sd.xzBM]?.ToString();
                string gh_dl = row[sd.ghBM]?.ToString();
                // 边界标记
                string bj = row["YSBJ"]?.ToString();
                bj = bj == "边界内" ? "边界内" : "边界外";

                // 筛选
                // 村庄建设用地转农用地
                if (czjsKeys.Contains(xz_dl) && nydKeys.Contains(gh_dl))
                {
                    double mj = (double)row["SHAPE_Area"]/10000;

                    string key = $"{bj}+{xz_dl}";

                    if (czyd2nyd.ContainsKey(key))
                    {
                        czyd2nyd[key] += mj;
                    }
                    else
                    {
                        czyd2nyd.Add(key, mj);
                    }
                }

                // 农用地转村庄建设用地
                if (nydKeys.Contains(xz_dl) && czjsKeys.Contains(gh_dl))
                {
                    double mj = (double)row["SHAPE_Area"] / 10000;

                    string key = $"{bj}+{gh_dl}";

                    if (nyd2czyd.ContainsKey(key))
                    {
                        nyd2czyd[key] += mj;
                    }
                    else
                    {
                        nyd2czyd.Add(key, mj);
                    }
                }


            }

            // 写入。排序
            sd.CZYD2NYD = czyd2nyd.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);

            sd.NYD2CZYD = nyd2czyd.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);

        }

        // 写入Word 说明
        private void WriteWord(StateData sd)
        {
            string modelWord = $@"CCTool.Data.Word.说明书.docx";
            string targetWord = sd.OutputWord;
            // 复制模板
            DirTool.CopyResourceFile(modelWord, targetWord);


            ///// 现状说明
            string xzsm = "";    // 现状说明
            // 指标
            string xzq = sd.XZQ;    // 村庄名称
            string xzqmj = sd.XZQMJ.RoundWithFill(sd.Digit);    // 村界面积

            string xzNydmj = GetArea(sd, sd.XZDict, "农用地小计");     // 现状农用地面积
            string xzNydbl = GetBL(sd.XZDict, "农用地小计");    // 现状农用地比例

            string xzJsydmj = GetArea(sd, sd.XZDict, "建设用地小计");      // 现状建设用地面积  建设用地小计
            string xzJsydbl = GetBL(sd.XZDict, "建设用地小计");   // 现状建设用地比例

            string xzWlydmj = GetArea(sd, sd.XZDict, "未利用地小计");    // 现状未利用地面积
            string xzWlydbl = GetBL(sd.XZDict, "未利用地小计");   // 现状未利用地比例


            // 现状文本说明
            xzsm += $"依据《四川省村规划编制指南》（2024年修订版），规划以最新年度变更调查为基础，在衔接镇级国土空间总体规划底数底图上，对数据进行地类转换、细化和边界修订，按《国土空间调查、规划、用途管制用地用海分类指南》的要求确定工作底数（下称基期数据）。";
            xzsm += $"{xzq}土地总面积{xzqmj}公顷（扣除城镇开发边界），";

            // 三大类用地
            xzsm += $"其中农用地面积{xzNydmj}公顷，占土地总面积的{xzNydbl}%；建设用地面积{xzJsydmj}公顷，占土地总面积的{xzJsydbl}%；未利用地面积{xzWlydmj}公顷，占土地总面积的{xzWlydbl}%。\r";
            // 农用地
            xzsm += $"（一）农用地\r";
            xzsm += $"{xzq}农用地面积{xzNydmj}公顷，其中";

            // 耕地、园地、林地、草地、农业设施建设用地
            List<string> keys01 = new List<string>() { "耕地", "园地", "林地", "草地", "农业设施建设用地" };
            xzsm += GetAreaDesc(sd, sd.XZDict, keys01);

            // 陆地水域
            List<string> ldsyKeys = new List<string>() { "1703", "1704", "1705" };
            xzsm += GetAreaDescLDSY(sd, sd.XZDict, ldsyKeys, "陆地水域");

            // 田坎
            xzsm += $"其他土地中田坎面积{GetArea(sd, sd.XZDict, "2303")}公顷，占土地面积的{GetBL(sd.XZDict, "2303")}%。\r";

            // 建设用地
            xzsm += $"（二）建设用地\r";
            xzsm += $"{xzq}建设用地面积{xzJsydmj}公顷，其中";

            // 村庄建设用地
            List<string> czjsKeys = new List<string>()
            {
                "070101", "070102", "070103", "0702", "070301", "070302", "0704", "0801", "0802" ,
                "080301", "080302", "080401", "080402", "080403", "080404", "080405", "080501", "080502" ,
                "080601", "080602", "080603", "080701", "080702", "080703", "080704",
                "090101", "090102", "090103", "090104", "090105", "0902", "0903", "0904",
                "100101", "100102", "100103",
                "110101", "110102", "110103", "1102",
                "1207", "120801", "120802", "120803", "1209",
                "1301", "1302", "1303", "1304", "1305", "1306", "1307", "1308", "1309" ,
                "1310", "1312", "1401", "1402", "16",
            };
            xzsm += GetAreaDescLDSY(sd, sd.XZDict, czjsKeys, "村庄建设用地");

            // 村区域基础设施用地
            List<string> qyjsKeys = new List<string>()
            {
                "1201", "1202", "1203", "1204", "1205", "1206", "1311",
            };
            xzsm += GetAreaDescLDSY(sd, sd.XZDict, qyjsKeys, "区域基础设施用地");

            // 其他建设用地
            List<string> qtjsKeys = new List<string>()
            {
                "1002", "1003", "1501", "1502", "1503", "1504", "1505", "1506", "1507",
            };
            xzsm += GetAreaDescLDSY(sd, sd.XZDict, qtjsKeys, "其他建设用地");

            xzsm = xzsm[..^1] + "。\r";

            // 未利用地
            xzsm += $"（三）未利用地\r";
            xzsm += $"{xzq}未利用地面积{xzWlydmj}公顷，其中";

            // 河流水面、空闲地、后备耕地、盐碱地、沙地等
            List<string> keys02 = new List<string>() { "1701", "2301", "2302", "2304", "2305", "2306", "2307" };
            xzsm += GetAreaDesc02(sd, sd.XZDict, keys02);

            xzsm = xzsm[..^1] + "。";


            ///// 规划说明
            string ghsm = "";     // 规划说明
            // 耕地
            ghsm += $"第一节 农用地布局\r（一）耕地布局\r";
            ghsm += $"在严格落实上位规划下达耕地保护目标基础上通过农用地整治、宅基地复垦等土地整治措施进一步优化耕地布局，补充耕地数量，提高耕地质量与连片度。" +
                $"至规划期末，耕地面积{GetArea(sd, sd.GHDict, "耕地")}公顷，占比为{GetBL(sd.GHDict, "耕地")}%，";

            // 耕保面积验证
            string gb = GetArea(sd, sd.GHDict, "耕地").ToDouble() > sd.GBMJ.ToDouble() ? $"满足耕地保有量不低于{sd.GBMJ}公顷的要求。\r" : $"不满足耕地保有量不低于{sd.GBMJ}公顷的要求。\r";
            ghsm += gb;

            // 园地
            ghsm += $"（二）园地布局\r";
            ghsm += $"规划至2035年，园地面积{GetArea(sd, sd.GHDict, "园地")}公顷，占比为{GetBL(sd.GHDict, "园地")}%，{GetBH(sd, "园地")}。\r";

            // 林地
            ghsm += $"（三）林地布局\r";
            ghsm += $"规划至2035年，林地面积{GetArea(sd, sd.GHDict, "林地")}公顷，占比为{GetBL(sd.GHDict, "林地")}%，{GetBH(sd, "林地")}。\r";

            // 草地
            ghsm += $"（四）草地布局\r";
            ghsm += $"规划至2035年，草地面积{GetArea(sd, sd.GHDict, "草地")}公顷，占比为{GetBL(sd.GHDict, "草地")}%，{GetBH(sd, "草地")}。\r";

            // 陆地水域
            ghsm += $"（五）陆地水域\r规划至2035年，";
            List<string> ldsyKeys_gh = new List<string>() { "1703", "1704", "1705" };
            ghsm += GetAreaDescLDSY02(sd, ldsyKeys_gh, "陆地水域");
            ghsm += "\r";

            // 其他土地
            ghsm += $"（六）其他土地\r";
            ghsm += $"规划至2035年，田坎面积{GetArea(sd, sd.GHDict, "2303")}公顷，占比为{GetBL(sd.GHDict, "2303")}%，{GetBH(sd, "2303")}。\r";

            // 农业设施建设用地布局
            ghsm += $"（七）农业设施建设用地布局\r规划";

            List<string> nyjsKeys_gh = new List<string>() { "060101", "060102", "060201", "060202", "060203" };
            ghsm += GetAreaDescLDSY02(sd, nyjsKeys_gh, "农业设施建设用地");
            ghsm += "\r";


            ///建设用地布局
            // 村庄用地
            # region

            ghsm += $"第二节 建设用地布局\r";
            ghsm += $"（一）村庄建设用地布局\r";

            // 重点
            ghsm += GetAreaDescLDSY04(sd, czjsKeys);
            ghsm += GetAreaDescZJ(sd);


            // 1.居住用地
            ghsm += $"1.居住用地\r";
            ghsm += $"坚持“一户一宅”原则，结合实际情况，在充分尊重民意基础上不新增聚居点。至规划期末，";

            List<string> jzKeys_gh = new List<string>() { "070101", "070102", "070103", "0702", "070301", "070302", "0704" };
            ghsm += GetAreaDescLDSY03(sd, jzKeys_gh);
            ghsm += "\r";

            // 2.公共管理与公共服务用地
            ghsm += $"2.公共管理与公共服务用地\r";
            ghsm += $"规划至2035年，";

            List<string> ggKeys_gh = new List<string>() { "0801", "0802", "080301", "080302", "080401", "080402", "080403", "080404", "080405", "080501", "080502", "080601", "080602", "080603", "080701", "080702", "080703", "080704" };
            ghsm += GetAreaDescLDSY03(sd, ggKeys_gh);
            ghsm += "\r";

            // 3.商业服务业用地
            ghsm += $"3.商业服务业用地\r";
            ghsm += $"结合XXXX等发展需求，通过盘活闲置农村宅基地用作商业用途，新增商业用地，逐步完善村域乡村旅游商业配套。至规划期末，";

            List<string> syKeys_gh = new List<string>() { "090101", "090102", "090103", "090104", "090105", "0902", "0903", "0904" };
            ghsm += GetAreaDescLDSY03(sd, syKeys_gh);
            ghsm += "\r";

            // 4.工业用地
            ghsm += $"4.工业用地\r";
            ghsm += $"规划至2035年，";

            List<string> gyKeys_gh = new List<string>() { "100101", "100102", "100103" };
            ghsm += GetAreaDescLDSY03(sd, gyKeys_gh);
            ghsm += "\r";

            // 5.仓储用地
            ghsm += $"5.仓储用地\r";
            ghsm += $"规划至2035年，";

            List<string> ccKeys_gh = new List<string>() { "110101", "110102", "110103", "1102" };
            ghsm += GetAreaDescLDSY03(sd, ccKeys_gh);
            ghsm += "\r";

            // 6.交通运输用地
            ghsm += $"6.交通运输用地\r";
            ghsm += $"规划至2035年，";

            List<string> jtKeys_gh = new List<string>() { "1207", "120801", "120802", "120803", "1209" };
            ghsm += GetAreaDescLDSY03(sd, jtKeys_gh);
            ghsm += "\r";

            // 7.公用设施用地
            ghsm += $"7.公用设施用地\r";
            ghsm += $"规划至2035年，";

            List<string> gyssKeys_gh = new List<string>() { "1301", "1302", "1303", "1304", "1305", "1306", "1307", "1308", "1309", "1310", "1312" };
            ghsm += GetAreaDescLDSY03(sd, gyssKeys_gh);
            ghsm += "\r";

            // 8.绿地与开敞空间用地
            ghsm += $"8.绿地与开敞空间用地\r";
            ghsm += $"规划至2035年，";

            List<string> ldKeys_gh = new List<string>() { "1401", "1402", "1403" };
            ghsm += GetAreaDescLDSY03(sd, ldKeys_gh);
            ghsm += "\r";

            // 9.留白用地
            ghsm += $"9.留白用地\r";
            ghsm += $"为应对未来发展的不确定性，妥善处理好规划操作性和前瞻性的关系，为乡村未来新产业新业态的发展预留空间，规划留白用地{sd.GHDict["09"].RoundWithFill(sd.Digit)}公顷。\r";

            # endregion

            // 区域基地设施用地
            ghsm += $"（二）区域基础设施用地布局\r至规划期末，";

            List<string> jcssKeys_gh = new List<string>() { "1201", "1202", "1203", "1204", "1205", "1206", "1311" };
            ghsm += GetAreaDescLDSY03(sd, jcssKeys_gh);
            ghsm += "\r";

            // 其他建设用地布局
            ghsm += $"（三）其他建设用地布局\r至规划期末，";

            List<string> tsKeys_gh = new List<string>() { "1002", "1003", "1501", "1502", "1503", "1504", "1505", "1506", "1507" };
            ghsm += GetAreaDescLDSY03(sd, tsKeys_gh);
            ghsm += "\r";

            // 土地利用控制
            ghsm += $"（四）土地利用控制\r地块划分及编码。居民点建设用地和集体经营性建设用地按照“村编码—地块编码”的二级编码方式对建新地块进行编码，村编码为字母XXX（XXX村），地块编码为阿拉伯数字，如XXX—01表示XXX村01号地块。\r规定性指标。包括土地用途、用地面积、容积率、建筑限高、建筑密度等要求。除已注明取下限值的，如无特殊情况，建筑密度、容积率和建筑高度均取上限值。（详见附表4）\r";

            ///未利用地布局
            // 河流水面布局
            ghsm += $"第三节 未利用地布局\r（一）河流水面布局\r严格落实河道范围管理有关要求，保护河流生态环境，禁止新增除区域基础设施以外的建设用地。规划";
            List<string> hlKeys_gh = new List<string>() { "1701" };
            ghsm += GetAreaDescLDSY03(sd, hlKeys_gh);
            ghsm += "\r";

            // 其他土地布局
            ghsm += $"（二）其他土地布局\r规划至2035年，";
            List<string> qtKeys_gh = new List<string>() { "2301", "2302", "2304", "2305", "2306", "2307" };
            ghsm += GetAreaDescLDSY03(sd, qtKeys_gh);
            ghsm += "\r";




            WordTool.WordRepalceText(targetWord, "{底图底数}", xzsm);
            WordTool.WordRepalceText(targetWord, "{用地布局}", ghsm);

        }


        // 计算农村建设用地和农用地的增减情况
        private string GetAreaDescZJ(StateData sd)
        {
            string result = "";
            
            Dictionary<string, double> dict_cz2ny = sd.CZYD2NYD;
            // 村庄建设用地转为农用地总和
            double cz_js = dict_cz2ny.Sum(x => x.Value);
            result += $"具体增减情况如下：\r结合村民意愿，通过土地综合整治，减少村庄建设用地{cz_js.RoundWithFill(sd.Digit)}公顷。";

            
            double bjn_cz_js = 0;    // 边界内减少面积
            double bjy_cz_js = 0;    // 边界外减少面积
            double total_cz_js = 0;   // 总减少面积

            string str_bjn_cz_js = "";   // 边界内描述文本
            string str_bjy_cz_js = "";   // 边界外描述文本

            // 边界内，边界外
            foreach (var item in dict_cz2ny)
            {
                string bj = item.Key.Split("+")[0];    // 边界标记
                string dl = item.Key.Split("+")[1];   // 地类编码

                string  dlmc = GlobalData.dic_ydyh_new[dl];   // 地类名称

                double mj = item.Value;    //  面积

                total_cz_js += mj;

                if (bj == "边界内")
                {
                    bjn_cz_js += mj;
                    str_bjn_cz_js += $"{dlmc}{mj.RoundWithFill(sd.Digit)}公顷，";
                }
                else
                {
                    bjy_cz_js += mj;
                    str_bjy_cz_js += $"{dlmc}{mj.RoundWithFill(sd.Digit)}公顷，";
                }
            }

            result += $"其中：村庄建设边界内减少村庄建设用地{bjn_cz_js.RoundWithFill(sd.Digit)}公顷（包含{str_bjn_cz_js[..^1]}），";
            result += $"村庄建设边界外减少村庄建设用地{bjy_cz_js.RoundWithFill(sd.Digit)}公顷（包含{str_bjy_cz_js[..^1]}）。\r";



            Dictionary<string, double> dict_ny2cz = sd.NYD2CZYD;
            // 农用地转为村庄建设用地总和
            double cz_zj = dict_ny2cz.Sum(x => x.Value);
            result += $"完善基础设施、发展农旅融合产业，新增村庄建设用{cz_zj.RoundWithFill(4)}公顷。";


            double bjn_cz_zj = 0;    // 边界内减少面积
            double bjy_cz_zj = 0;    // 边界外减少面积
            double total_cz_zj = 0;   // 总减少面积

            string str_bjn_cz_zj = "";   // 边界内描述文本
            string str_bjy_cz_zj = "";   // 边界外描述文本

            // 边界内，边界外
            foreach (var item in dict_ny2cz)
            {
                string bj = item.Key.Split("+")[0];    // 边界标记
                string dl = item.Key.Split("+")[1];   // 地类编码

                string dlmc = GlobalData.dic_ydyh_new[dl];   // 地类名称

                double mj = item.Value;    //  面积

                total_cz_zj += mj;

                if (bj == "边界内")
                {
                    bjn_cz_zj += mj;
                    str_bjn_cz_zj += $"{dlmc}{mj.RoundWithFill(sd.Digit)}公顷，";
                }
                else
                {
                    bjy_cz_zj += mj;
                    str_bjy_cz_zj += $"{dlmc}{mj.RoundWithFill(sd.Digit)}公顷，";
                }
            }

            result += $"其中：村庄建设边界内新增村庄建设用地{bjn_cz_zj.RoundWithFill(sd.Digit)}公顷（包含{str_bjn_cz_zj[..^1]}），";
            result += $"村庄建设边界外减少村庄建设用地{bjy_cz_zj.RoundWithFill(sd.Digit)}公顷（包含{str_bjy_cz_zj[..^1]}）。\r";
            
            return result;
        }


        // 获取面积
        private string GetArea(StateData sd, Dictionary<string, double> dict, string key, bool isChange = false)
        {
            string re = "";

            if (dict.ContainsKey(key))
            {
                key = isChange ? GlobalData.dic_ydyh_new[key] : key;

                re = dict[key].RoundWithFill(sd.Digit);
            }
            else
            {
                re = "0.00";
            }
            return re;
        }

        // 获取比例
        private string GetBL(Dictionary<string, double> dict, string key, bool isChange = false)
        {
            string re = "";

            if (dict.ContainsKey(key))
            {
                key = isChange ? GlobalData.dic_ydyh_new[key] : key;

                re = (dict[key] / dict["合计"] * 100).RoundWithFill(2);
            }
            else
            {
                re = "0.00";
            }
            return re;
        }

        // 获取面积变化
        private string GetBH(StateData sd, string key, bool isChange = false)
        {
            string re = "";

            double xzmj = 0;
            double ghmj = 0;

            key = isChange ? GlobalData.dic_ydyh_new[key] : key;

            if (sd.XZDict.ContainsKey(key))
            {
                xzmj = sd.XZDict[key];
            }
            if (sd.GHDict.ContainsKey(key))
            {
                ghmj = sd.GHDict[key];
            }

            if (xzmj > ghmj)
            {
                re = $"较现状减少{(xzmj - ghmj).RoundWithFill(sd.Digit)}公顷";
            }
            else if (xzmj < ghmj)
            {
                re = $"较现状增加{(ghmj - xzmj).RoundWithFill(sd.Digit)}公顷";
            }
            else
            {
                re = $"与现状保持一致";
            }

            return re;
        }


        // 面积和比例描述
        private string GetAreaDesc(StateData sd, Dictionary<string, double> dict, List<string> keys01)
        {
            string sm = "";
            foreach (var key in keys01)
            {
                if (dict.ContainsKey(key))
                {
                    if (dict[key] != 0)
                    {
                        string mj = dict[key].RoundWithFill(sd.Digit);
                        string bl = (dict[key] / dict["合计"] * 100).RoundWithFill(2);
                        sm += $"{key}面积{mj}公顷，占土地总面积的{bl}%；";
                    }
                }
            }

            return sm;
        }


        // 面积和比例描述、、 代码转名称
        private string GetAreaDesc02(StateData sd, Dictionary<string, double> dict, List<string> keys01)
        {
            string sm = "";
            foreach (var key in keys01)
            {
                if (dict.ContainsKey(key))
                {
                    if (dict[key] != 0)
                    {
                        // 编号转名称
                        string mc = GlobalData.dic_ydyh_new[key];

                        string mj = dict[key].RoundWithFill(sd.Digit);
                        string bl = (dict[key] / dict["合计"] * 100).RoundWithFill(2);
                        sm += $"{mc}面积{mj}公顷，占土地总面积的{bl}%；";
                    }
                }
            }

            return sm;
        }


        // 面积和比例描述——类似，陆地水域
        private string GetAreaDescLDSY(StateData sd, Dictionary<string, double> dict, List<string> keys01, string totalName)
        {
            string sm = "";
            double total = 0;   // 总面积
            string fx = "";     // 分项统计
            foreach (var key in keys01)
            {
                if (dict.ContainsKey(key))
                {
                    if (dict[key] != 0)
                    {
                        // 编号转名称
                        string mc = GlobalData.dic_ydyh_new[key];

                        string mj = dict[key].RoundWithFill(sd.Digit);
                        string bl = (dict[key] / dict["合计"] * 100).RoundWithFill(2);
                        fx += $"{mc}面积{mj}公顷、";

                        total += dict[key];
                    }
                }
            }
            // 如果有面积
            if (total != 0)
            {
                if (fx != "")
                {
                    fx = fx[..^1];
                }

                sm = $"{totalName}面积{total.RoundWithFill(sd.Digit)}公顷（{fx}），占土地总面积的{(total / dict["合计"] * 100).RoundWithFill(2)}%；";
            }

            return sm;
        }

        // 面积和比例描述——类似，陆地水域，   但没有括号
        private string GetAreaDescLDSY02(StateData sd, List<string> keys01, string totalName)
        {
            string sm = "";
            double total = 0;   // 总面积
            string fx = "";     // 分项统计
            foreach (var key in keys01)
            {
                string re = "";

                double xzmj = 0;
                double ghmj = 0;

                if (sd.XZDict.ContainsKey(key))
                {
                    xzmj = sd.XZDict[key];
                }
                if (sd.GHDict.ContainsKey(key))
                {
                    ghmj = sd.GHDict[key];
                }
                // 现状规划都没有面积，则不统计
                if (xzmj == 0 && ghmj == 0)
                {
                    continue;
                }

                if (xzmj > ghmj)
                {
                    re = $"较现状减少{(xzmj - ghmj).RoundWithFill(sd.Digit)}公顷";
                }
                else if (xzmj < ghmj)
                {
                    re = $"较现状增加{(ghmj - xzmj).RoundWithFill(sd.Digit)}公顷";
                }
                else
                {
                    re = $"与现状保持一致";
                }

                total += ghmj;

                string mc = GlobalData.dic_ydyh_new[key];

                fx += $"{mc}面积{ghmj.RoundWithFill(sd.Digit)}公顷，占比为{(ghmj / sd.GHDict["合计"] * 100).RoundWithFill(2)}%，{re}；";
            }

            if (fx != "")
            {
                fx = fx = $"{fx[..^1]}。";
            }

            sm = $"{totalName}面积{total.RoundWithFill(sd.Digit)}公顷， 占比为{(total / sd.XZDict["合计"] * 100).RoundWithFill(2)}%，其中，{fx}";

            return sm;
        }

        // 面积和比例描述——类似，陆地水域，   但没有括号， 没有总用地
        private string GetAreaDescLDSY03(StateData sd, List<string> keys01)
        {
            string fx = "";     // 分项统计
            foreach (var key in keys01)
            {
                string re = "";

                double xzmj = 0;
                double ghmj = 0;

                if (sd.XZDict.ContainsKey(key))
                {
                    xzmj = sd.XZDict[key];
                }
                if (sd.GHDict.ContainsKey(key))
                {
                    ghmj = sd.GHDict[key];
                }

                // 现状规划都没有面积，则不统计
                if (xzmj == 0 && ghmj == 0)
                {
                    continue;
                }

                if (xzmj > ghmj)
                {
                    re = $"较现状减少{(xzmj - ghmj).RoundWithFill(sd.Digit)}公顷";
                }
                else if (xzmj < ghmj)
                {
                    re = $"较现状增加{(ghmj - xzmj).RoundWithFill(sd.Digit)}公顷";
                }
                else
                {
                    re = $"与现状保持一致";
                }

                string mc = GlobalData.dic_ydyh_new[key];

                fx += $"{mc}面积{ghmj.RoundWithFill(sd.Digit)}公顷，占比为{(ghmj / sd.GHDict["合计"] * 100).RoundWithFill(2)}%，{re}；";
            }

            if (fx != "")
            {
                fx = $"{fx[..^1]}。";
            }
            return fx;
        }

        // 面积和比例描述——类似，陆地水域，   只算总计
        private string GetAreaDescLDSY04(StateData sd, List<string> keys01)
        {
            string result = "";

            double xzmj_total = 0;
            double ghmj_total = 0;

            foreach (var key in keys01)
            {

                double xzmj = 0;
                double ghmj = 0;

                if (sd.XZDict.ContainsKey(key))
                {
                    xzmj = sd.XZDict[key];
                }
                if (sd.GHDict.ContainsKey(key))
                {
                    ghmj = sd.GHDict[key];
                }

                xzmj_total += xzmj;
                ghmj_total += ghmj;
            }

            result += $"至规划期末，村庄建设用地面积为{ghmj_total.RoundWithFill(sd.Digit)}公顷，占总用地面积{(ghmj_total / sd.XZDict["合计"] * 100).RoundWithFill(2)}%，";


            if (xzmj_total > ghmj_total)
            {
                result += $"较现状减少{(xzmj_total - ghmj_total).RoundWithFill(sd.Digit)}公顷";
            }
            else if (xzmj_total < ghmj_total)
            {
                result += $"较现状增加{(ghmj_total - ghmj_total).RoundWithFill(sd.Digit)}公顷";
            }
            else
            {
                result += $"与现状保持一致";
            }

            result += "。";

            return result;
        }


        // 根据扣除系数计算净面积和田坎面积
        private static void GetReportData(StateData sd)
        {
            // 平均扣除系数
            double total_kcxs = 0;
            long count = 0;

            Table table = sd.DLTB.TargetTable();
            using RowCursor rowCursor = table.Search();
            while (rowCursor.MoveNext())
            {
                Row row = rowCursor.Current;
                var kcxs = row["KCXS"];
                if (kcxs != null)
                {
                    double va = kcxs.ToString().ToDouble();
                    if (va != 0)
                    {
                        total_kcxs += va;
                        count += 1;
                    }
                }
            }

            sd.KCXS = total_kcxs / count;

            // 计算田坎面积和耕地净面积
            sd.xzTK = CalTKMJ(sd, sd.xzPath, sd.xzBM, sd.xzField);

            sd.ghTK = CalTKMJ(sd, sd.ghPath, sd.ghBM, sd.ghField);

        }

        private static double CalTKMJ(StateData sd, string ghPath, string ghBM, string ghField)
        {
            // 规划面积计算
            Arcpy.AddField(ghPath, sd.areaField, "DOUBLE");
            Arcpy.CalculateField(ghPath, sd.areaField, $"!{ghField}!");
            Arcpy.AddField(ghPath, sd.XS, "DOUBLE");
            Arcpy.CalculateField(ghPath, sd.XS, "0");

            // 更新扣除系数
            // 获取原始图层和标识图层
            FeatureLayer originFeatureLayer = ghPath.TargetFeatureLayer();
            FeatureLayer identityFeatureLayer = sd.DLTB.TargetFeatureLayer();
            // 获取原始图层和标识图层的要素类
            FeatureClass originFeatureClass = ghPath.TargetFeatureClass();
            FeatureClass identityFeatureClass = sd.DLTB.TargetFeatureClass();

            // 获取目标图层和源图层的要素游标
            using RowCursor originCursor = originFeatureClass.Search();

            // 遍历源图层的要素
            while (originCursor.MoveNext())
            {
                using Feature originFeature = (Feature)originCursor.Current;
                double maxOverlapArea = 0;
                double kccs = 0;

                // 如果不是耕地，直接赋值为0
                string bm = originFeature[ghBM]?.ToString() ?? "";
                if (bm == "" || bm[..2] != "01")
                {
                    continue;
                }

                // 获取源要素的几何
                ArcGIS.Core.Geometry.Geometry originGeometry = originFeature.GetShape();

                // 创建空间查询过滤器，以获取与源要素有重叠的目标要素
                SpatialQueryFilter spatialFilter = new SpatialQueryFilter
                {
                    FilterGeometry = originGeometry,
                    SpatialRelationship = SpatialRelationship.Intersects
                };

                // 在目标图层中查询与源要素重叠的要素
                using (RowCursor identityCursor = identityFeatureClass.Search(spatialFilter))
                {
                    while (identityCursor.MoveNext())
                    {
                        using Feature identityFeature = (Feature)identityCursor.Current;
                        // 获取目标要素的几何
                        ArcGIS.Core.Geometry.Geometry identityGeometry = identityFeature.GetShape();

                        // 计算源要素与目标要素的重叠面积
                        ArcGIS.Core.Geometry.Geometry intersection = GeometryEngine.Instance.Intersection(originGeometry, identityGeometry);
                        double overlapArea = Math.Round((intersection as ArcGIS.Core.Geometry.Polygon).Area, 2);
                        double originArea = Math.Round((originGeometry as ArcGIS.Core.Geometry.Polygon).Area, 2);

                        // 如果重叠面积大于当前最大重叠面积，则更新最大重叠面积和目标要素
                        if (overlapArea > maxOverlapArea && identityFeature["KCXS"] is not null)
                        {
                            maxOverlapArea = overlapArea;
                            // 重叠Feature
                            kccs = identityFeature["KCXS"].ToString().ToDouble();
                        }
                    }
                }

                // 如果找到与源要素有最大重叠的目标要素，则将其属性复制到源要素
                double mj = originFeature[sd.areaField].ToString().ToDouble();
                if (kccs != 0)
                {
                    originFeature[sd.XS] = kccs;
                    originFeature[sd.areaField] = mj * (1 - kccs);
                }
                else    // 不符合要求的情况下
                {
                    originFeature[sd.XS] = sd.KCXS;
                    originFeature[sd.areaField] = mj * (1 - sd.KCXS);
                }
                // 更新源图层中的源要素
                originFeature.Store();
            }

            // 获取田坎面积
            return GetTK(ghPath, sd.XS, ghField);
        }



        // 获取田坎面积
        private static double GetTK(string fcPath, string kcField, string mjField)
        {
            double tk = 0;
            Table table = fcPath.TargetTable();
            using RowCursor rowCursor = table.Search();
            while (rowCursor.MoveNext())
            {
                using Row row = rowCursor.Current;
                var kc = row[kcField];
                var mj = row[mjField];
                if (kc is not null && mj is not null)
                {
                    tk += kc.ToString().ToDouble() * mj.ToString().ToDouble();
                }
            }
            return tk;
        }

        // 统计表格1
        private void WriteExcel01(StateData sd)
        {
            string outPutExcel = sd.OutputExcel;
            string excel_sheet = outPutExcel + @"\现状面积统计表$";

            // 设置小数位数
            ExcelTool.SetDigit(excel_sheet, new List<int>() { 3 }, 3, sd.Digit);

            // 属性映射
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excel_sheet);
            int sheetIndex = ExcelTool.GetSheetIndex(excel_sheet);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 打开工作表
            Worksheet sheet = wb.Worksheets[sheetIndex];

            // 逐行处理
            for (int i = 3; i <= sheet.Cells.MaxDataRow; i++)
            {
                //  获取目标cell
                string mapStr = sheet.Cells[i, 5]?.StringValue ?? "";
                // 属性映射
                if (sd.XZDict.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 3].Value = sd.XZDict[mapStr];   // 面积
                    sheet.Cells[i, 4].Value = sd.XZDict[mapStr] / sd.XZDict["合计"] * 100;   // 占比
                }
            }
            // 保存
            wb.Save(excelFile);
            wb.Dispose();

            // 删除0值行
            ExcelTool.DeleteNullRow(excel_sheet, new List<int>() { 3, 4 }, 3);
            // 删除指定列
            ExcelTool.DeleteCol(excel_sheet, new List<int>() { 5 });

        }

        // 统计表格2
        private void WriteExcel02(StateData sd)
        {
            string outPutExcel = sd.OutputExcel;
            string excel_sheet = outPutExcel + @"\国土空间用途结构调整表$";

            // 设置小数位数
            ExcelTool.SetDigit(excel_sheet, new List<int>() { 3, 5, 7 }, 3, sd.Digit);

            // 属性映射
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excel_sheet);
            int sheetIndex = ExcelTool.GetSheetIndex(excel_sheet);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 打开工作表
            Worksheet sheet = wb.Worksheets[sheetIndex];

            // 逐行处理
            for (int i = 3; i <= sheet.Cells.MaxDataRow; i++)
            {
                //  获取目标cell
                string mapStr = sheet.Cells[i, 8]?.StringValue ?? "";
                // 属性映射
                if (sd.XZDict.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 3].Value = sd.XZDict[mapStr];   // 面积
                    sheet.Cells[i, 4].Value = sd.XZDict[mapStr] / sd.XZDict["合计"] * 100;   // 占比
                }
                if (sd.GHDict.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 5].Value = sd.GHDict[mapStr];   // 面积
                    sheet.Cells[i, 6].Value = sd.GHDict[mapStr] / sd.GHDict["合计"] * 100;   // 占比
                }
            }
            // 保存
            wb.Save(excelFile);
            wb.Dispose();

            // 删除0值行
            ExcelTool.DeleteNullRow(excel_sheet, new List<int>() { 3, 4, 5, 6 }, 3);
            // 删除指定列
            ExcelTool.DeleteCol(excel_sheet, new List<int>() { 8 });

        }

        // 统计表格3
        private void WriteExcel03(StateData sd)
        {
            string outPutExcel = sd.OutputExcel;
            string excel_sheet = outPutExcel + @"\规划前后三大类面积对比表$";

            // 指标汇总
            Dictionary<string, double> dic_xz = StatisticsDictSDL(sd.XZDict);
            Dictionary<string, double> dic_gh = StatisticsDictSDL(sd.GHDict);
            // 更新指标字典
            sd.XZDict = dic_xz;
            sd.GHDict = dic_gh;

            // 设置小数位数
            ExcelTool.SetDigit(excel_sheet, new List<int>() { 3, 5, 7, }, 3, sd.Digit);

            // 属性映射
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excel_sheet);
            int sheetIndex = ExcelTool.GetSheetIndex(excel_sheet);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 打开工作表
            Worksheet sheet = wb.Worksheets[sheetIndex];

            // 逐行处理
            for (int i = 3; i <= sheet.Cells.MaxDataRow; i++)
            {
                //  获取目标cell
                string mapStr = sheet.Cells[i, 8]?.StringValue ?? "";
                // 属性映射
                if (dic_xz.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 3].Value = dic_xz[mapStr];   // 面积
                    sheet.Cells[i, 4].Value = dic_xz[mapStr] / dic_xz["合计"] * 100;   // 占比
                }
                if (dic_gh.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 5].Value = dic_gh[mapStr];   // 面积
                    sheet.Cells[i, 6].Value = dic_gh[mapStr] / dic_gh["合计"] * 100;   // 占比
                }
            }
            // 保存
            wb.Save(excelFile);
            wb.Dispose();

            // 删除0值行
            //ExcelTool.DeleteNullRow(excel_sheet, new List<int>() { 3, 4, 5, 6 }, 3);
            // 删除指定列
            ExcelTool.DeleteCol(excel_sheet, new List<int>() { 8 });

        }


        // 统计表格4
        private void WriteExcel04(StateData sd)
        {
            string outPutExcel = sd.OutputExcel;
            string excel_sheet = outPutExcel + @"\规划前后建设用地面积对比表$";

            // 指标汇总
            Dictionary<string, double> dic_xz = StatisticsDict(sd.XZDict);
            Dictionary<string, double> dic_gh = StatisticsDict(sd.GHDict);
            // 更新指标字典
            sd.XZDict = dic_xz;
            sd.GHDict = dic_gh;

            // 设置小数位数
            ExcelTool.SetDigit(excel_sheet, new List<int>() { 2, 4, 6, }, 3, sd.Digit);

            // 属性映射
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excel_sheet);
            int sheetIndex = ExcelTool.GetSheetIndex(excel_sheet);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 打开工作表
            Worksheet sheet = wb.Worksheets[sheetIndex];

            // 逐行处理
            for (int i = 3; i <= sheet.Cells.MaxDataRow; i++)
            {
                //  获取目标cell
                string mapStr = sheet.Cells[i, 7]?.StringValue ?? "";
                // 属性映射
                if (dic_xz.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 2].Value = dic_xz[mapStr];   // 面积
                    sheet.Cells[i, 3].Value = dic_xz[mapStr] / dic_xz["合计"] * 100;   // 占比
                }
                if (dic_gh.ContainsKey(mapStr))
                {
                    sheet.Cells[i, 4].Value = dic_gh[mapStr];   // 面积
                    sheet.Cells[i, 5].Value = dic_gh[mapStr] / dic_gh["合计"] * 100;   // 占比
                }
            }
            // 保存
            wb.Save(excelFile);
            wb.Dispose();

            // 删除0值行
            ExcelTool.DeleteNullRow(excel_sheet, new List<int>() { 2, 3, 4, 5 }, 3);
            // 删除指定列
            ExcelTool.DeleteCol(excel_sheet, new List<int>() { 7 });

        }

        // 指标小计
        private Dictionary<string, double> StatisticsDict(Dictionary<string, double> oriDict)
        {
            Dictionary<string, double> dict = new Dictionary<string, double>(oriDict);
            // 村庄建设用地小计
            List<string> czyds = new List<string>()
            {
                "070101","070102","070103","0702","070301","070302","0704","0801","0802","080301","080302","080401","080402","080403","080404","080405","080501","080502","080601","080602","080603","080701","080702","080703","080704","090101","090102","090103","090104","090105","0902","0903","0904","100101","100102","100103","1207","120801","120802","120803","1209","1301","1302","1303","1304","1305","1306","1307","1308","1309","1310","1312","1401","1402","1403","16"
            };

            // 基础设施用地小计
            List<string> jcssyds = new List<string>()
            {
                "1201","1202","1203","1204","1205","1206","1311"
            };

            // 其他建设用地小计
            List<string> qtjsyds = new List<string>()
            {
                "1002","1003","1501","1502","1503","1504","1505","1506","1507"
            };

            // 合并key
            dict = BaseTool.MergeDict(dict, czyds, "村庄建设用地小计");
            dict = BaseTool.MergeDict(dict, jcssyds, "基础设施用地小计");
            dict = BaseTool.MergeDict(dict, qtjsyds, "其他建设用地小计");

            // 建设用地小计
            List<string> jsyds = new List<string>()
            {
                "村庄建设用地小计","基础设施用地小计","其他建设用地小计"
            };

            dict = BaseTool.MergeDict(dict, jsyds, "建设用地小计");

            return dict;
        }

        // 指标小计-三大类
        private Dictionary<string, double> StatisticsDictSDL(Dictionary<string, double> oriDict)
        {
            Dictionary<string, double> dict = new Dictionary<string, double>(oriDict);

            List<string> gd = new List<string>() { "0101", "0102", "0103", };
            List<string> yd = new List<string>() { "0201", "0202", "0203", "0204", "0205", };
            List<string> ld = new List<string>() { "0301", "0302", "0303", "0304", };
            List<string> cd = new List<string>() { "0401", "0402", "0403", };
            List<string> nyssyd = new List<string>() { "060101", "060102", "060201", "060202", "060203", };

            // 合并key
            dict = BaseTool.MergeDict(dict, gd, "耕地");
            dict = BaseTool.MergeDict(dict, yd, "园地");
            dict = BaseTool.MergeDict(dict, ld, "林地");
            dict = BaseTool.MergeDict(dict, cd, "草地");
            dict = BaseTool.MergeDict(dict, nyssyd, "农业设施建设用地");

            // 再合并
            List<string> nyd = new List<string>() { "耕地", "园地", "林地", "草地", "农业设施建设用地", "1703", "1704", "1705", "2302", };
            List<string> wjyd = new List<string>() { "1701", "2301", "2302", "2304", "2305", "2306", "2307" };
            List<string> nydLdsy = new List<string>() { "1703", "1704", "1705" };    // 农用地里的陆地水域


            dict = BaseTool.MergeDict(dict, nyd, "农用地小计");
            dict = BaseTool.MergeDict(dict, wjyd, "未利用地小计");
            dict = BaseTool.MergeDict(dict, nydLdsy, "农用地陆地水域");

            return dict;
        }


        private void combox_areaField_DropDown(object sender, EventArgs e)
        {
            UITool.AddAllFloatFieldsToComboxPlus(combox_fc.ComboxText(), combox_areaField);
        }

        private void btn_help_Click(object sender, RoutedEventArgs e)
        {
            string url = "";
            UITool.Link2Web(url);
        }


        private List<string> CheckData(StateData sd, string in_data_1, string in_field_1, string in_data_2, string in_field_2)
        {
            List<string> result = new List<string>();

            // 现状
            if (in_data_1 != "" && in_field_1 != "")
            {
                // 检查字段值是否符合要求
                string result_value = CheckTool.CheckFieldValue(in_data_1, in_field_1, sd.BMList);
                if (result_value != "")
                {
                    result.Add(result_value);
                }
            }

            // 规划
            if (in_data_2 != "" && in_field_2 != "")
            {
                // 检查字段值是否符合要求
                string result_value = CheckTool.CheckFieldValue(in_data_2, in_field_2, sd.BMList);
                if (result_value != "")
                {
                    result.Add(result_value);
                }
            }

            // DLTB中的KCXS
            if (sd.DLTB is not null)
            {
                // 检查字段值是否符合要求
                string result_value = CheckTool.IsHaveFieldInTarget(sd.DLTB, "KCXS");
                if (result_value != "")
                {
                    result.Add(result_value);
                }
            }


            return result;
        }

        private void combox_fc_gh_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_fc_gh);
        }

        private void combox_bmField_gh_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc_gh.ComboxText(), combox_bmField_gh);
        }

        private void combox_areaField_gh_DropDown(object sender, EventArgs e)
        {
            UITool.AddAllFloatFieldsToComboxPlus(combox_fc_gh.ComboxText(), combox_areaField_gh);
        }

        private void combox_dltb_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_dltb);
        }

        private void combox_jsbj_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_jsbj);
        }
    }

    // 状态数据
    public class StateData
    {
        public string XZQ { get; set; }
        public double XZQMJ { get; set; }

        public double KCXS { get; set; }

        public double xzTK { get; set; }
        public double ghTK { get; set; }

        public string xzPath { get; set; }
        public string ghPath { get; set; }

        public string xzBM { get; set; }
        public string ghBM { get; set; }

        public string DLTB { get; set; }
        public string JSBJ { get; set; }

        public string xzField { get; set; }
        public string ghField { get; set; }
        public string areaField { get; set; } = "BJYMJ";

        public Dictionary<string, double> XZDict { get; set; }
        public Dictionary<string, double> GHDict { get; set; }

        public string OutputFolder { get; set; }
        public string OutputExcel { get; set; }
        public string OutputWord { get; set; }

        public string UnitName { get; set; }
        public int Digit { get; set; }

        public string XS { get; set; } = "newXS";   // 新的扣除系数字段

        public List<string> BMList { get; set; } = new List<string>()
        {
            "0101", "0102", "0103", "0201", "0202", "0203", "0204", "0205", "0301", "0302", "0303", "0304", "0401", "0402", "0403",
            "0501", "0502", "0503", "0504", "0506", "060101", "060102", "060201", "060202", "060203", "070101", "070102", "070103",
            "0702", "070301", "070302", "0704", "0801", "0802", "080301", "080302", "080401", "080402", "080403", "080404", "080405",
            "080501", "080502", "080601", "080602", "080603", "080701", "080702", "080703", "080704", "090101", "090102", "090103",
            "090104", "090105", "0902", "0903", "0904", "100101", "100102", "100103", "1002", "1003", "110101", "110102", "110103",
            "1102", "1201", "1202", "1203", "1204", "1205", "1206", "1207", "120801", "120802", "120803", "1209", "1301", "1302", "1303",
            "1304", "1305", "1306", "1307", "1308", "1309", "1310", "1311", "1312", "1401", "1402", "1403", "1501", "1502", "1503", "1504",
            "1505", "1506", "1507", "16", "1701", "1702", "1703", "1704", "1705", "1706", "2301", "2302", "2303", "2304", "2305", "2306", "2307",
        };

        // 耕地保有量面积，公顷
        public string GBMJ { get; set; }

        // 村庄建设用地转农用地
        public Dictionary<string, double> CZYD2NYD { get; set; }
        // 农用地转村庄建设用地
        public Dictionary<string, double> NYD2CZYD { get; set; }

    }

}
